package com.bytecub.common.biz;

import com.bytecub.common.constants.BCConstants;
import com.bytecub.common.enums.BCErrorEnum;
import com.bytecub.common.enums.TopicTypeEnum;
import com.bytecub.common.exception.BCGException;
import com.bytecub.common.metadata.ProductFuncTypeEnum;
import com.bytecub.utils.StringUtils;

/**
 * * ByteCub.cn. * Copyright (c) 2020-2020 All Rights Reserved. * * @author bytecub@163.com songbin
 * * @version Id: TopicBiz.java, v 0.1 2020-12-09 Exp $$
 */
public class TopicBiz {
    /** 从topic中解析物模型类型 系统前缀/deviceCode/suffix */
    public static String parseDeviceCode(String topic) {
        try {
            String[] splits = topic.split("/");
            return splits[2];
        } catch (Exception e) {
            throw BCGException.genException(BCErrorEnum.MQTT_TOPIC_INVALID, topic);
        }
    }

    /** 从topic中解析物模型类型 系统前缀/funcType/identifier/deviceCode */
    public static String parseFuncType(String topic) {
        try {
            String[] splits = topic.split("/");
            return splits[3].toUpperCase();
        } catch (Exception e) {
            throw BCGException.genException(BCErrorEnum.MQTT_TOPIC_INVALID, topic);
        }
    }

    /** 从topic中解析物模型类型 系统前缀/funcType/identifier/deviceCode */
    public static ProductFuncTypeEnum parseFuncTypeEnum(String topic) {
        try {
            String[] splits = topic.split("/");
            return ProductFuncTypeEnum.explain(splits[3].toUpperCase());
        } catch (Exception e) {
            throw BCGException.genException(BCErrorEnum.MQTT_TOPIC_INVALID, topic);
        }
    }

    /** 根据协议编码组装订阅主题，用于内部MQTT客户端订阅 */
    public static String buildTopicByProduct() {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX + "/#";
    }

    public static String buildServiceInvoke(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/service/invoke";
    }

    public static String buildPropertySet(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/set";
    }

    public static String buildPropertySetSub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/set/sub";
    }

    /** 设备属性读取 */
    public static String buildPropertyGet(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/get";
    }

    /** 设备属性读取 */
    public static String buildPropertyGetSub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/get/sub";
    }

    /** 设备属性上报 */
    public static String buildPropertyReport(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX + productCode + "/" + deviceCode + "/prop";
    }

    public static String buildPropertyReportSub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX + productCode + "/" + deviceCode + "/prop/sub";
    }

    public static String buildEventReport(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX + productCode + "/" + deviceCode + "/event";
    }

    public static String buildEventReportSub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX + productCode + "/" + deviceCode + "/event/sub";
    }

    public static String buildUpgradeSet(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/upgrade/set";
    }

    public static String buildUpgradeSetSub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_DOWN_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/upgrade/set/sub";
    }

    /** 服务调用返回结果上报 */
    public static String buildServiceInvokeReply(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/message/reply";
    }

    /** 服务调用返回结果上报 */
    public static String buildServiceInvokeReplySub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/message/reply/sub";
    }

    /** 设备属性读取响应 */
    public static String buildPropertyGetReply(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/getreply";
    }

    /** 设备属性读取响应 */
    public static String buildPropertyGetReplySub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/property/getreply/sub";
    }

    /** 设备升级响应 */
    public static String buildUpgradeReply(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/upgrade/reply";
    }

    /** 设备升级响应 */
    public static String buildUpgradeReplySub(String deviceCode, String productCode) {
        return BCConstants.MQTT.GLOBAL_UP_PREFIX
                + productCode
                + "/"
                + deviceCode
                + "/upgrade/reply/sub";
    }

    /**
     * 替换topic中的产品编码和设备编码,唯一作用是在系统收到来自网关设备上报子设备消息时将topic进行替换
     *
     * @param orgTopic String 原始topic
     * @param productCode String 目标产品编码
     * @param deviceCode String 目标设备编码
     * @return 替换产品编码和设备编码后的新topic
     */
    public static String topicFromGw2Sub(String orgTopic, String productCode, String deviceCode) {
        if (StringUtils.isEmpty(orgTopic)) {
            return orgTopic;
        }
        String[] splits = orgTopic.split("/");
        StringBuffer sb =
                new StringBuffer(splits[0])
                        .append("/")
                        .append(productCode)
                        .append("/")
                        .append(deviceCode);
        for (int index = 3; index < splits.length; index++) {
            sb.append("/").append(splits[index]);
        }
        return sb.toString();
    }

    public static String buildTopicByType(
            String deviceCode, String productCode, TopicTypeEnum topicTypeEnum) {
        switch (topicTypeEnum) {
            case PROP_REPORT:
                return TopicBiz.buildPropertyReport(deviceCode, productCode);
            case EVENT_REPORT:
                return TopicBiz.buildEventReport(deviceCode, productCode);
            case SERVICE_INVOKE_REPLY:
                return TopicBiz.buildServiceInvokeReply(deviceCode, productCode);
            case PROP_READ_REPLY:
                return TopicBiz.buildPropertyGetReply(deviceCode, productCode);
            case FIRMWARE_UPGRADE_REPLY:
                return TopicBiz.buildUpgradeReply(deviceCode, productCode);
            case SERVICE_INVOKE:
                return TopicBiz.buildServiceInvoke(deviceCode, productCode);
            case PROP_SET:
                return TopicBiz.buildPropertySet(deviceCode, productCode);
            case PROP_READ:
                return TopicBiz.buildPropertyGet(deviceCode, productCode);
            case FIRMWARE_SET:
                return TopicBiz.buildUpgradeSet(deviceCode, productCode);
            default:
                throw new BCGException("topic类型错误");
        }
    }

    public static void main(String[] args) {
        String topic = "bcup/e4skexj7ktclxnpn/dev_868739053274977/prop";
        String pCode = "p1";
        String dCode = "d1";
        String newTopic = TopicBiz.topicFromGw2Sub(topic, pCode, dCode);
        System.out.println(newTopic);
    }
}
